package design.mode.factory;


/**
 * 简单工厂模式通用写法
 * <p>
 * 优点:<br/>
 * 简单工厂模式的结构简单，调用方便。对于外界给定的信息，可以很方便地创建出相应的产品。工厂和产品的职责区分明确。<br/>
 * 缺点:<br/>
 * 简单工厂模式的工厂类单一，负责所有产品的创建，但当产品基数增多时，工厂类代码会非常臃肿，违背高聚合原则。<br/>
 * </p>
 */
public class CommonSimpleFactory {

    public static void main(String[] args) {

        IProduct productA = SimpleFactory.makeProduct(1);
        IProduct productB = SimpleFactory.makeProduct(2);
        IProduct productC = SimpleFactory.makeProduct(3);
        IProduct productD = SimpleFactory.makeProduct(4);

        productA.doSomething();
        productB.doSomething();
        productC.doSomething();
        productD.doSomething();

    }

    /**
     * 抽象产品接口
     */
    public interface IProduct {
        void doSomething();
    }
    /**
     * <p>
     * 简单工厂模式（Simple Factory Pattern）又叫作静态工厂方法模式（StaticFactory Method Pattern），简单来说，简单工厂模式有一个具体的工厂类，可以生成多个不同的产品，属于创建型设计模式。简单工厂模式不在GoF 23种设计模式之列。
     * </p>
     * <p>
     * 场景：对于产品种类相对较少的情况，考虑使用简单工厂模式可以很方便地创建所需产品。使用简单工厂模式的客户端只需要传入工厂类的参数，不需要关心如何创建对象的逻辑。
     * <p/>
     */
    static class SimpleFactory {

        private SimpleFactory() {

        }

        public static IProduct makeProduct(int kind) {
            switch (kind) {
                case Const.PRODUCT_A:
                    return new ProductA();
                case Const.PRODUCT_B:
                    return new ProductB();
                case Const.PRODUCT_C:
                    return new ProductC();
            }
            return new IProduct() {
                @Override
                public void doSomething() {
                    System.out.println("没有该产品");
                }
            };
        }
    }

    /**
     * 常量
     */
    interface Const {
        int PRODUCT_A = 1;
        int PRODUCT_B = 2;
        int PRODUCT_C = 3;
    }

    /**
     * 具体产品A
     */
    static class ProductA implements IProduct {
        @Override
        public void doSomething() {
            System.out.println("Product A doSomething");
        }
    }

    /**
     * 具体产品B
     */
    static class ProductB implements IProduct {
        @Override
        public void doSomething() {
            System.out.println("Product B doSomething");
        }
    }

    /**
     * 具体产品C
     */
    static class ProductC implements IProduct {
        @Override
        public void doSomething() {
            System.out.println("Product C doSomething");
        }
    }
}
